package series

// Bitmap 用于高效标记null值（每行仅占1bit）
type Bitmap struct {
	bits []uint64
	size int // 总位数，新增字段以支持Append操作
}

func NewBitmap(size int) *Bitmap {
	return &Bitmap{
		bits: make([]uint64, (size+63)/64),
		size: size,
	}
}

func (b *Bitmap) Set(i int, v bool) {
	idx, pos := i/64, uint(i%64)
	if v {
		b.bits[idx] |= 1 << pos
	} else {
		b.bits[idx] &^= 1 << pos
	}
}

func (b *Bitmap) Get(i int) bool {
	idx, pos := i/64, uint(i%64)
	return b.bits[idx]&(1<<pos) != 0
}

func (b *Bitmap) Clone() *Bitmap {
	newBits := make([]uint64, len(b.bits))
	copy(newBits, b.bits)
	return &Bitmap{
		bits: newBits,
		size: b.size,
	}
}

// AppendOne 在Bitmap末尾追加一个新值
func (b *Bitmap) AppendOne(v bool) {
	idx, pos := b.size/64, uint(b.size%64)

	// 检查是否需要扩容
	if idx >= len(b.bits) {
		b.bits = append(b.bits, 0)
	}

	// 设置新位的值（默认为false，仅当v为true时需要设置）
	if v {
		b.bits[idx] |= 1 << pos
	}

	b.size++
}

// Append 将另一个 Bitmap 的所有位追加到当前 Bitmap 的末尾
// 调用后，当前 Bitmap 的长度将变为原长度 + other 的长度
func (b *Bitmap) Append(other *Bitmap) {
	if other == nil || other.size == 0 {
		return
	}

	oldSize := b.size
	b.size += other.size

	// 计算需要的容量并扩容
	needLen := (b.size + 63) / 64
	if needLen > len(b.bits) {
		newBits := make([]uint64, needLen)
		copy(newBits, b.bits)
		b.bits = newBits
	}

	wordOff := oldSize / 64
	bitOff := uint(oldSize % 64)

	if bitOff == 0 {
		// 如果当前在字边界，直接拷贝整个字
		copy(b.bits[wordOff:], other.bits)
	} else {
		// 否则需要按位合并
		for i, word := range other.bits {
			b.bits[wordOff+i] |= word << bitOff
			if wordOff+i+1 < len(b.bits) {
				b.bits[wordOff+i+1] |= word >> (64 - bitOff)
			}
		}
	}

	// 清除最后一个字中未使用的位，保持Bitmap干净
	if b.size%64 != 0 {
		lastIdx := len(b.bits) - 1
		b.bits[lastIdx] &= (1 << (b.size % 64)) - 1
	}
}
